import Vapor
import Foundation
import FluentKit
struct FileUpload: RouteCollection {
    func boot(routes: RoutesBuilder) throws {
        let files = routes.grouped("files")
        files.post("upload", use: upload)
        files.post("bundleUpload", use: self.bundleUpload)
    }
    
    @Sendable
    func upload(request: Request) async throws -> JSONResponse<String> {
        // Get the uploaded file
        guard let file = try? request.content.get(File.self, at: "file") else {
            return JSONResponse(
                message: "No file found in request",
                code: -1,
                data: ""
            )
        }
        var type = try? request.content.get(String.self, at: "type")
        if type == nil {
            type = "image"
        }
        if type == "image" {
            let filename = "\(UUID().uuidString)_\(file.filename)"
            let publicPath = request.application.directory.publicDirectory
            try FileManager.default.createDirectory(
                atPath: publicPath,
                withIntermediateDirectories: true
            )
            let path = publicPath + filename
            try await request.fileio.writeFile(file.data, at: path)
            let host = Environment.get("HOST_NAME") ?? request.application.http.server.configuration.hostname
            let port = Environment.get("HOST_PORT") ?? "8080"
            var https = "https"
            if host == "localhost" {
                https = "http"
            }
            return JSONResponse(
                message: "File uploaded successfully",
                code: 0,
                data: "\(https)://\(host):\(port)/\(filename)"
            )
        } else if (type == "bundle"){
            let filename = "index.zip"
            let bundlePath = request.application.directory.publicDirectory + "/jsbundles"
            try FileManager.default.createDirectory(
                atPath: bundlePath,
                withIntermediateDirectories: true
            )
            let path = bundlePath + filename
            if let appVersion = request.headers["appVersion"].first {
                try await request.fileio.writeFile(file.data, at: path)
                let host = Environment.get("HOST_NAME") ?? "localhost"
                let port = Environment.get("HOST_PORT") ?? "8080"
                var https = "https"
                if host == "localhost" {
                    https = "http"
                }
                let url = "\(https)://\(host):\(port)/\(filename)"
                if let bundle = try await JSBundleModel.query(on: request.db)
                    .filter(\.$appVersion == appVersion)
                    .first() {
                    bundle.downloadUrl = url
                    bundle.md5 = UUID().uuidString
                    bundle.uploadDate = Date()
                    try await bundle.save(on: request.db)
                } else {
                    let jsBundle = JSBundleModel(id: UUID().uuidString,appVersion: appVersion, jsVersion: "1.0.0", downloadUrl: url, md5: UUID().uuidString)
                    try await jsBundle.save(on: request.db)
                }
                return JSONResponse(
                    message: "File uploaded successfully",
                    code: 0,
                    data: url
                )
            } else {
                return JSONResponse(
                    message: "未知App版本",
                    code: -1,
                    data: nil
                )
            }
            
        }
        return JSONResponse(
            message: "Invalid File Type",
            code: -1,
            data: ""
        )
    }
    
    @Sendable
    func bundleUpload(request: Request) async throws -> JSONResponse<String> {
        // Get the uploaded file
        guard let file = try? request.content.get(File.self, at: "file") else {
            return JSONResponse(
                message: "No file found in request",
                code: -1,
                data: ""
            )
        }
        let filename = "\(UUID().uuidString)_\(file.filename)"
        let publicPath = request.application.directory.publicDirectory
        try FileManager.default.createDirectory(
            atPath: publicPath,
            withIntermediateDirectories: true
        )
        let path = publicPath + filename
        try await request.fileio.writeFile(file.data, at: path)
        let host = Environment.get("HOST_NAME") ?? "localhost"
        let port = Environment.get("HOST_PORT") ?? "8080"
        var https = "https"
        if host == "localhost" {
            https = "http"
        }
        return JSONResponse(
            message: "File uploaded successfully",
            code: 0,
            data: "\(https)://\(host):\(port)/\(filename)"
        )
    }
}
